#include "USART.h"

void init_USART() {
	// Enable the receiver and transmitter
	UCSR0B = (1 << RXEN0 | 1 << TXEN0);
	
	// Define the USART frame.
	// We want 8 data bits, no parity bit and one stop bit
	UCSR0C = (1 << UCSZ00 | 1 << UCSZ01 | 0 << UPM01 | 0 << USBS0);
	
	// Initialize the UBRR register to achieve the desired BAUDRATE.
	// We assume normal asynchronous mode (thats why we divide by 16)
	UBRR0 = UBRR_VAL;
}

void send_byte_USART(uint8_t byte) {
	//while(!(UCSR0A & 1 << UDRE0)){
		; // Wait till the USART Data Register is empty
	//}
	UDR0 = byte;
}

void send_cmd_USART(command_t cmd, uint8_t* params, uint8_t length) {
	send_byte_USART(cmd);
	for(unsigned int i = 0; i < length; i++) {
		send_byte_USART(params[i]);
	}
}

uint8_t receive_byte_USART(uint8_t* byte) {
	while (!(UCSR0A & (1<<RXC0))) {
		; // Wait till there is unread data in the receive buffer
	}
	
	// Check for errors
	if(UCSR0A & (1 << FE0) || UCSR0A & (1 << DOR0) || UCSR0A & (1 << UPE0)) {
		if(UCSR0A & (1 << FE0)){
			errno = FRAME_ERROR_USART;
		}else if(UCSR0A & (1 << UPE0)){
			errno = PARITY_ERROR_USART;
		}else if(UCSR0A & (1 << DOR0)){
			errno = OVERFLOW_USART;
		}
		*byte = UDR0;
		return -1;
	}
	
	*byte = UDR0;
	return 0;
}

uint8_t receive_cmd_results_USART(uint8_t* data, int length) {
	for(unsigned int i = 0; i < length; i++) {
		if(receive_byte_USART(data+i) == -1) {
			return -1;
		}
	}
	return 0;	
}